package com.marketlive.entity.account;

/*
(C) Copyright MarketLive. 2006. All rights reserved.
MarketLive is a trademark of MarketLive, Inc.
Warning: This computer program is protected by copyright law and international treaties.
Unauthorized reproduction or distribution of this program, or any portion of it, may result
in severe civil and criminal penalties, and will be prosecuted to the maximum extent
possible under the law.
*/

import java.util.Collection;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.marketlive.entity.IEntity;
import org.marketlive.entity.IPrimaryKey;
import org.marketlive.entity.account.IAccountSet;
import org.marketlive.entity.account.ICustomer;
import org.marketlive.entity.account.ICustomerHome;
import org.marketlive.system.encryption.*;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.hibernate.Session;
import org.hibernate.Query;

import com.marketlive.entity.EntityHome;
import com.marketlive.entity.IntegerPk;

/**
 * Interface to the Customer entity Home object, which provides creation and finder methods for <code>Customer</code>
 * entities.
 */
public class CustomerHome extends EntityHome implements ICustomerHome {
    /**
     * The LogFactory of the CustomerHome class.
     */
    private static Log log = LogFactory.getLog(CustomerHome.class);

    /** Reference to the encryptor class to encrypt passwords. */
    private IEncryptor encryptor;

    public void setEncryptor(IEncryptor encryptor) {
        this.encryptor = encryptor;
    }

    /** Reference to the decryptor class to decrypt passwords. */
    private IDecryptor decryptor;

    public void setDecryptor(IDecryptor decryptor) {
        this.decryptor = decryptor;
    }

    /** Reference to the KeyStore Manager. */
    private IKeyStoreManager keyStoreManager;

    /** Injects the KeyStore Manager reference into this class. */
    public void setKeyStoreManager(IKeyStoreManager keyStoreManager) {
        this.keyStoreManager = keyStoreManager;
    }

    /**
     * Constructor: Instantiate a Customer Home Object.
     *
     * @throws Exception if can not create a customer home object
     */
    public CustomerHome() throws Exception {
        super(Customer.ENTITY_TYPE, Customer.class);
        Customer.setEntityHome(this);
    }

    /**
     * @inheritDoc
     */
    public IPrimaryKey getPk(final String pkString) {
        int pkInt = -1;
        try {
            pkInt = Integer.parseInt(pkString);
        } catch (NumberFormatException e) {
            throw new RuntimeException("pkString for Customer must be an integer.");
        }
        return new IntegerPk("customer", pkInt);
    }

    /**
     * @inheritDoc
     */
    public IEntity get(final IPrimaryKey pk) {
        Customer a = new Customer();
        a.setPk(pk);
        return a;
    }

    /**
     * @inheritDoc
     */
    public ICustomer create(final IAccountSet accountSet, final String email, final String userName, final String password) {
        Customer customer = new Customer(email, userName, password);
        //customer.setAccountSet(accountSet);
        customer.setEmail(email);
        customer.setUserName(userName);
        customer.setPassword(password);
        super.create(customer);
        return (ICustomer) customer;
    }


    /**
     * @inheritDoc
     */
    public Collection findByEmail(final IAccountSet accountSet, final String email) {
        return getHibernateTemplate().find("from Customer where accountSet = ? and email = ?", new Object[] { accountSet, email });
    }


    /**
     * @inheritDoc
     */
    public Collection findByUserName(final IAccountSet accountSet, final String userName) {
        return getHibernateTemplate().find("from Customer where accountSet = ? and upper(USER_NAME)= upper(?)", new Object[] { accountSet, userName });
    }

    /**
     * @inheritDoc
     * @deprecated as of MarketLive 5.5 without replacement. Will be removed in the next major release since
     * soft delete will not be supported.
     */
    public void markDeleted(final ICustomer customer) {
        customer.setDateModified(getTimestamp());
        customer.setDateDeleted(getTimestamp());
        customer.setDeleted(true);
        getHibernateTemplate().update(customer);
    }

    /**
     * @inheritDoc
     */
    public ICustomer findByCode(final String code) {
        List customers = getHibernateTemplate().find("from Customer where delete_flag = 0 and code = ?", new Object[] { code });
        if (customers.isEmpty()) {
            return null;
        }
        if (customers.size() > 1) {
            throw new IllegalArgumentException("More than one customer was found with code: " + code);
        }
        return (ICustomer)customers.get(0);
    }

    /**
     * @inheritDoc
     */
    public String encryptPassword(ICustomer customer) throws EncryptionException {
        if (customer.getPassword() != null) {
            return encryptor.encrypt(customer.getPassword());
        } else {
            return null;
        }
    }

    /**
     * @inheritDoc
     */
    public String encryptPassword(String password) throws EncryptionException {
        if (password != null) {
            return encryptor.encrypt(password);
        } else {
            return null;
        }
    }

    /**
     * @inheritDoc
     */
    public String getEncryptionKeyCode() {
        return keyStoreManager.getKeyCode();
    }

    /**
     * @inheritDoc
     */
    public boolean comparePasswords(String encryptedPassword1, String encryptedPassword2) throws DecryptionException {
        return decryptor.compare(encryptedPassword1, encryptedPassword2);
    }

}
